package ${importPackage};

<#assign hasAllAnyImportFields = false>
<#list po.relOneList as rel>
    <#list po.importFields as field>
        <#if field.modelName == rel.name>
            <#assign hasAllAnyImportFields = true>
            <#break>
        </#if>
    </#list>
    <#if hasAllAnyImportFields><#break></#if>
</#list>
<#list po.relManyList as rel>
    <#list po.importFields as field>
        <#if field.modelName == rel.name>
            <#assign manyMainField = rel.mainField>
            <#assign hasAllAnyImportFields = true>
            <#break>
        </#if>
    </#list>
    <#if hasAllAnyImportFields><#break></#if>
</#list>
<#if hasAllAnyImportFields>
import com.odianyun.util.BeanMapper;
import com.google.common.collect.Maps;
</#if>
import com.google.common.collect.Lists;
import ${servicePackage}.${po.name}Service;
import ${dtoPackage}.${po.name}ImportDTO;
import ${dtoPackage}.${po.name}DTO;
import com.odianyun.project.support.data.impt.IAsyncDataImportAware;
import com.odianyun.project.support.data.impt.IAsyncDataImportHandler;
import com.odianyun.project.support.data.model.DataImportParam;
import com.odianyun.project.support.data.model.ExcelMsg;
import com.odianyun.project.util.ValidUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
<#list po.relOneList as rel>
    <#assign hasAnyImportFields = false>
    <#list po.importFields as field>
        <#if field.modelName == rel.name>
            <#assign hasAnyImportFields = true>
            <#break>
        </#if>
    </#list>
    <#if hasAnyImportFields>
import ${dtoPackage}.${rel.name}DTO;
    </#if>
</#list>
<#list po.relManyList as rel>
    <#assign hasAnyImportFields = false>
    <#list po.importFields as field>
        <#if field.modelName == rel.name>
            <#assign hasAnyImportFields = true>
            <#break>
        </#if>
    </#list>
    <#if hasAnyImportFields>
import ${dtoPackage}.${rel.name}DTO;
    </#if>
</#list>

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import javax.validation.Validator;
<#if hasAllAnyImportFields>
import java.util.Map;
</#if>
import java.util.List;
import java.util.Set;

@Component
public class ${po.name}ImportHandler implements IAsyncDataImportHandler<${po.name}ImportDTO> {
    @Resource
    private IAsyncDataImportAware<${po.name}ImportDTO> asyncDataImportAware;
    @Resource
    private ${po.name}Service service;
    @Resource
    private Validator validator;

    @Override
    public List<ExcelMsg> importData(List<${po.name}ImportDTO> data, DataImportParam param) throws Exception {
        <#if manyMainField??>
        Map<${manyMainField.typeName}, ${po.name}DTO> preAddMap = Maps.newHashMap();
        <#else>
        List<${po.name}DTO> preAddList = Lists.newArrayListWithExpectedSize(data.size());
        </#if>
        List<ExcelMsg> errors = Lists.newArrayList();
        for (${po.name}ImportDTO dto : data) {
            Set<ConstraintViolation<${po.name}ImportDTO>> violations = validator.validate(dto);
            if (violations != null && violations.size() > 0) {
                List<String> msgs = ValidUtils.extractErrorMessage(violations);
                errors.add(new ExcelMsg(dto.getRow(), StringUtils.join(msgs, ",")));
            } else {
                <#if manyMainField??>
                ${po.name}DTO ${po.uncapName}Bean = preAddMap.get(dto.get${manyMainField.capName}());
                if (${po.uncapName}Bean == null) {
                    ${po.uncapName}Bean = dto.convertTo(${po.name}DTO.class);
                    preAddMap.put(dto.get${manyMainField.capName}(), ${po.uncapName}Bean);
                }
                <#else>
                ${po.name}DTO ${po.uncapName}Bean = dto.convertTo(${po.name}DTO.class);
                preAddList.add(${po.uncapName}Bean);
                </#if>
                <#list po.relOneList as rel>
                    <#assign hasAnyImportFields = false>
                    <#list po.importFields as field>
                        <#if field.modelName == rel.name>
                            <#assign hasAnyImportFields = true>
                            <#break>
                        </#if>
                    </#list>
                    <#if hasAnyImportFields>
                    ${rel.name}DTO ${rel.uncapName}DTO = BeanMapper.create()
                    <#list po.importFields as f>
                        <#list rel.fields as rf>
                            <#if f.modelName == rel.name && f.name == rf.name && f.relName != f.name>
                    .keyMapping("${f.refName}", "${f.name}")
                            </#if>
                        </#list>
                    </#list>
                    .copy(dto, ${rel.name}DTO.class);
                ${po.uncapName}Bean.set${rel.name}(${rel.uncapName}DTO);
                    </#if>
                </#list>
                <#list po.relManyList as rel>
                    <#assign hasAnyImportFields = false>
                    <#list po.importFields as field>
                        <#if field.modelName == rel.name>
                            <#assign hasAnyImportFields = true>
                            <#break>
                        </#if>
                    </#list>
                    <#if hasAnyImportFields>
                List<${rel.name}DTO> ${rel.uncapName}List = ${po.uncapName}Bean.get${rel.name}List();
                if (${rel.uncapName}List == null) {
                    ${rel.uncapName}List = Lists.newArrayList();
                    ${po.uncapName}Bean.set${rel.name}List(${rel.uncapName}List);
                }
                ${rel.name}DTO ${rel.uncapName}DTO = BeanMapper.create()
                <#list po.importFields as f>
                    <#list rel.fields as rf>
                        <#if f.modelName == rel.name && f.name == rf.name && f.relName != f.name>
                .keyMapping("${f.relName}", "${f.name}")
                        </#if>
                    </#list>
                </#list>
                .copy(dto, ${rel.name}DTO.class);
                ${rel.uncapName}List.add(${rel.uncapName}DTO);
                    </#if>
                </#list>
            }
        }
        if (errors.isEmpty()) {
            <#if manyMainField??>
            service.batchAddWithTx(Lists.newArrayList(preAddMap.values()));
            <#else>
            service.batchAddWithTx(preAddList);
            </#if>
        }
        return errors;
    }

    @Override
    public IAsyncDataImportAware<${po.name}ImportDTO> getAsyncDataImportAware() {
        return asyncDataImportAware;
    }

    @Override
    public String getImportType() {
        return "${po.uncapName}Import";
    }
}
